a) Aufgabe
Die Arbeitsmappe LTelefonverzeichnis.xls enthält eine Anwendung, die ein kleines Objektmodell aus einer benutzerdefinierten Objektklasse und einer Auflistung implementiert. Das Bild unten zeigt die Benutzerschnittstelle. Die Namen und Telefonnummern, die man im oberen Eingabebereich eingibt, werden beim Klicken der Hinzufügen-Schaltfläche in internen Objekten gespeichert und die Objekte einer Auflistung hinzugefügt. Es wird eine Telefonliste aufgebaut. Ein Klick auf die Liste-Schaltfläche gibt alle gespeicherten Datenpaare in sortierter Reihenfolge im unteren Ausgabebereich aus. Ausserdem kann man einen Namen im 'Name'-Eingabefeld eingeben und über die Suchen-Schaltfläche die Telefonnummer suchen lassen.
Die Anwendung sei spezifiziert und die Benutzerschnittstelle
entworfen. Sie soll nun
implementiert werden (vgl.
Fallbeispiel Bibliothek, siehe auch
Übungsaufgabe "Telefonverzeichnis").
b) Entwurf des Objektmodells
Das folgende Bild skizziert die Objekte der laufenden Anwendung und die Objektvariablen, welche die Objektverweise speichern:
Das Programm benötigt also die folgenden Komponenten:
c) Implementation des Verzeichnisses
Für die Implementation des 'Auflistung'-Objekts findet man bereits einen geeigneten Objekttyp in VBA - die Collection-Klasse. Ein Collection-Objekt ist eine geordnete Folge von Elementen, auf die als Einheit Bezug genommen werden kann. Geordnet heisst, dass jedes Element, ausser dem ersten und dem letzten, einen Vorgänger und einen Nachfolger hat. Das bedeutet nicht, dass die Elemente sortiert sind. Die Objekttypen der Elemente können beliebig sein, sie dürfen sogar innerhalb einer Collection variieren. Man beachte, dass die Collection-Klasse zu VBA und nicht zum Excel-Objektmodell gehört. Sie steht damit nicht nur in Excel zur Verfügung, sondern in jedem Anwendungspaket, das VBA enthält.
Collection-Objekte besitzen im Wesentlichen die gleichen Eigenschaften und Methoden wie die Auflistungen im Objektmodell von Excel. In benutzerdefinierten Objektmodellen werden denn auch Collection-Objekte benutzt, um Auflistungen zu implementieren. Wir werden deshalb oft auch Collection-Objekte als Auflistungen bezeichnen.
Jede Collection besitzt eine Count-Eigenschaft, sowie eine Add-, eine Item- und eine Remove-Methode. Im Gegensatz zu einer Auflistung des Objektmodells von Excel erstellt die Add-Methode einer Collection kein neues Objekt, sondern fügt nur ein zuvor erstelltes der Collection hinzu. Jedes hinzugefügte Element erhält einen Index, so dass man mit der Item-Methode darauf zugreifen kann. Die Nummerierung der Indizes läuft von 1 bis Count. Die Remove-Methode entfernt ein Element wieder aus der Auflistung.
Collection-Objekte werden wie benutzerdefinierte Objekte mit dem Schlüsselwort New erstellt. Das Erstellen und Benutzen von benutzerdefinierten Objekten geschieht in drei Schritten:
Objektvariable vereinbaren, z.B.
Private Verzeichnis As Collection
'Verzeichnis' wird auf Modulebene vereinbart, damit man von allen Prozeduren des Moduls aus auf das Verzeichnis zugreifen kann.
Objekt erstellen und der Variablen zuweisen, z.B.
Set Verzeichnis = New Collection
Die Zeile muss innerhalb einer Prozedur stehen. New erzeugt eine Instanz der Klasse Collection und gibt einen Verweis darauf zurück. Anschliessend wird der Verweis der Objektvariablen zugewiesen.
Über die Variable auf die Eigenschaften und Methoden zugreifen, z.B.
Range("anzahl") = Verzeichnis.Count
Die Zeile gibt die Anzahl Elemente der Auflistung auf dem Bereich "anzahl" des laufenden Tabellenblatts aus.
d) Implementation der Einträge
Die 'Eintrag'-Objekte zur Speicherung der Personendaten werden analog erstellt. Allerdings braucht man zuvor eine geeignete Klasse. Der Abschnitt über benutzerdefinierte Objektklassen zeigt ausführlich, wie man eigene Objektklassen definiert. Das Telefonverzeichnis-Projekt gibt einen ersten Einblick.
Klassen werden in VBA in Klassenmodulen beschrieben. Ein Klassenmodul ist ein VBA-Modul, das die Definition einer Objektklasse mit ihren Eigenschaften und Methoden enthält. Erstellt wird ein Klassenmodul wie ein Standardmodul mit dem Projektexplorer. Das nächste Bild zeigt das Projekt Telefonverzeichnis mit einem Klassenmodul cEintrag. Dem Namen 'Eintrag' wurde ein 'c' vorangestellt, um ihn als Name einer Klasse (engl. class) zu kennzeichnen.
In der Anwendung Telefonverzeichnis besitzen die 'Eintrag'-Objekte zwei Eigenschaften: Name und Telefon. Eigenschaften sind öffentliche Variablen eines Klassenmoduls. Das Modul cEintrag benötigt also lediglich zwei öffentliche Variablen.
Klassenmodul: cEintrag
Option Explicit Public Name As String Public Telefon As String
Von dieser Klasse kann man nun wie von der Collection-Klasse mit dem Schlüsselwort New beliebig viele Instanzen erstellen. New erzeugt dabei für jede Instanz ein eigenes Variablenpaar Name und Telefon, so wie im Klassenmodul vereinbart. Das Erstellen und Benutzen der Instanzen geschieht wieder in drei Schritten:
Objektvariable vereinbaren. Als Objekttyp wird diesmal der Name der Klassenmoduls angegeben, z.B.
Dim neuerEintrag As cEintrag
Objekt erstellen und der Variablen zuweisen, z.B.
Set neuerEintrag = New cEintrag
Auf die Eigenschaften des Objekts zugreifen, z.B.
neuerEintrag.Name = Range("name")
neuerEintrag.Telefon = Range("telefon")Das neue Objekt kann nun der zuvor erstellten Verzeichnis-Auflistung hinzugefügt werden. Ohne Angabe einer Position, wird es am Ende der Auflistung angehängt. Die Elemente werden damit im Verzeichnis in der Reihenfolge gespeichert, in der sie eingegeben werden.
Verzeichnis.Add neuerEintrag
e) Implementation des Sortieralgorithmus
Möchte man die Einträge in alphabethischer Reihenfolge ausgeben lassen, so muss man das Verzeichnis zunächst sortieren. Algorithmen, die Listen sortieren, gibt es viele. Jeder hat Vor- und Nachteile, die sich oft erst bei konkreten Problemen zeigen. Der folgende Algorithmus wurde ohne Effizienzüberlegungen gewählt. Es soll lediglich das Arbeiten mit Auflistungen und Objektverweisen vertiefen.
Das "Sortieren durch Auswählen" arbeitet mit zwei Collection-Objekten. Zu Beginn enthält die erste Auflistung alle Elemente und die zweite ist leer. In alphabetischer Reihenfolge werden nun die Elemente der ersten Auflistung entnommen (ausgewählt) und jeweils am Ende der zweiten angehängt. Sobald die erste Auflistung leer ist, bricht der Algorithmus ab. Die zweite Auflistung enthält dann alle Elemente in sortierter Reihenfolge. Das Bild unten veranschaulicht an einem Beispiel den Zustand eines Verzeichnisses vor und nach der Sortierung. Es deutet an, dass tatsächlich nur Verweise, und nicht Objekte umsortiert werden.
Der folgende Entwurfscode formuliert den Algorithmus präziser. Die Implementation in VBA ist Gegenstand der nächsten Aufgabe.
Sortiere durch Auswählen
erstelle neues Verzeichnis (ohne Einträge)
Solange noch Einträge im alten Verzeichnis
suche kleinsten Eintrag im alten Verzeichnis
füge Eintrag am Ende des neuen Verzeichnis ein
entferne Eintrag aus altem Verzeichnis
ersetzte altes Verzeichnis durch neues Verzeichnis.
Suche kleinsten Eintrag im Verzeichnis
setze kleinster Eintrag = erster Eintrag
Für alle Einträge im Verzeichnis
Falls aktueller Eintrag < kleinster Eintrag
setze kleinster Eintrag = aktueller Eintrag.